/**
 * 请求模块
 * writen by Yanjun tang(312976625@qq.com)
 */

var app = getApp();


var ContentType = app.modules['ContentType'];
var Logger = app.modules['Logger'];
var Config = app.config;


/**
 * 用户认证凭证
 * 用户认证后的SessionId或Token
 */
var AuthenticationId = false;

/**
 * 请求拦截器
 */
var requestInterceptors = [];

function Request(url,method,data){
    this.url = url.indexOf('http') == 0 ? url : Config.API_HTTP_SERVER + url;
    this.data = data == undefined ? {} : data;

    //默认以表单的Form形式发送给服务端
    this.header = {
        "Content-type": ContentType.FormEncode
    };
    this.method = method;

    //响应的结果默认以Json处理
    this.dataType = 'json';

    //响应内容对象
    this.response = {};
}

//公共的请求完成的处理逻辑
Request.prototype.onRequestComplate = function(res){
    Logger.debug('response:'+JSON.stringify(res));
    Logger.debug('== request complate ==');
}

//公共的请求出错逻辑
Request.prototype.onRequestFail = function(res){
    Logger.error(res);
}

//设置header
Request.prototype.withHeaders = function(headers){
    if (headers.constructor == Object){
        headers = [headers];
    }
    for(var i=0;i<headers.length;i++){
        var h = headers[i];
        this.header[h.key] = h.value;
    }
    return this;
}

Request.prototype.getHeader = function(key){
    return this.header[key] == undefined ? '' : this.header[key];
}

//设置请求内容类型
Request.prototype.setContentType = function(contentType){
    this.header['Content-type'] = contentType;
    return this;
}

//设置响应回来的数据是哪种类型
Request.prototype.setDataType = function(dataType){
    this.dataType = dataType;
    return this;
}

//设置post请求数据
Request.prototype.setData = function(data){
    this.data = data;
    return this;
}

Request.prototype.getResponse = function(){
    return this.response;
}


Request.prototype.send = function(){
    Logger.debug('== request start ==');
    //执行所有拦截器 before
    var self = this;
    var promise = new Promise(function(reslove,reject){
        var interceptor = self.doInterceptors('before');
        if (interceptor.constructor == Object){
            var message = 'request is interrupted by:' + interceptor.name + ' interceptor';
            Logger.error(message);
            reject({ errcode:10001,message: message});
            return;
        }
        var requestObj = {
            url: self.url,
            data: self.data,
            header: self.header,
            method: self.method,
            dataType: self.dataType,
            success: function(res){
                self.response = res;
                //执行所有拦截器 after
                self.doInterceptors('after');
                reslove(res);
            },
            fail:function(res){
                self.onRequestFail(res);
                reject(res);
            },
            complete: function(res){
                self.onRequestComplate(res);
            },
        };
        Logger.debug('request:' + JSON.stringify(requestObj));

        //发送请求
        wx.request(requestObj);

        
    });
    return promise;
}

Request.prototype.doInterceptors = function(method) {
    for(var i=0;i<requestInterceptors.length;i++){
        var method = requestInterceptors[i][method];
        if(method != undefined){
            var success = method.call(this, this);
            if (!success){
                return requestInterceptors[i];
            }
        }
    }
    return true;
}



module.exports = {

    addInterceptor:function(interceptor){
        this.addInterceptors([interceptor]);
    },
    addInterceptors:function(interceptors){
        for(var i=0;i<interceptors.length;i++){
            requestInterceptors.push(interceptors[i]);
        }
    },
    /**
     * GET 请求
     */
    get:function(url,data){
        return new Request(url,'GET',data).send();
    },


    /**
     * POST 请求
     */
    post:function(url,data){
        return new Request(url, 'POST', data).send();
    },

    /**
     * PUT 请求
     */
    put:function(url,data){
        return new Request(url,'PUT',data).send();
    },

    /**
     * DELETE 请求
     */
    remove:function(url){
        return new Request(url,'DELETE').send();
    }
}